🏠↩︎ De vuelta a la página principal del curso
🚀 Objetivo de la unidad
Que el estudiante sea capaz de importar y exportar bases de datos de y en diferentes formatos, así como ejecutar transformaciones básicas sobre estas utilizando data frames y el paquete data.table.
Nota importante: Los siguientes módulos prácticos son lineales.
# install.packages("ggplot2")
library(ggplot2)
Recuerde que un data frame se compone de vectores. En el siguiente bloque de código, se instancian dos vectores inicialmente,
x <- 1:10
y <- 3 + sin(x)
df <- data.frame(x=x, sin_of_x=y) # Los vectores que compondrán un data frame deben ser del mismo tamaño
La función head devuelve las primeras 6 observaciones (filas) de un data frame.
head(df)
## x sin_of_x
## 1 1 3.841471
## 2 2 3.909297
## 3 3 3.141120
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
La función tail devuelve las últimas 6 observaciones de un data frame.
tail(df)
## x sin_of_x
## 5 5 2.041076
## 6 6 2.720585
## 7 7 3.656987
## 8 8 3.989358
## 9 9 3.412118
## 10 10 2.455979
Tanto head() como tail(), pueden recibir el argumento adicional n, que indicará cuántas observaciones devuelvolverá.
tail(df, n=2) # Imprime las dos últimas observaciones
## x sin_of_x
## 9 9 3.412118
## 10 10 2.455979
La función colnames() devuelve los nombres de las variables de un data frame.
colnames(df)
## [1] "x" "sin_of_x"
La función length() devuelve el número de vectores que componen a un data frame. El número de vectores será entonces igual al número de variables (columnas).
length(df)
## [1] 2
La función dim() devuelve un vector de tamaño 2 con las dimensiones del data frame. En la primer posición del vector, se devolverá el número de observaciones, y en la segunda posición, el número de variables.
dim(df)
## [1] 10 2
Recuerde que un data frame es la versión bidimensional de una lista.
typeof(df)
## [1] "list"
La función str() devuelve el tipo y tamaño de cada vector que compone a un data frame. A esto se le conoce como la “estructura” de un data frame.
str(df)
## 'data.frame': 10 obs. of 2 variables:
## $ x : int 1 2 3 4 5 6 7 8 9 10
## $ sin_of_x: num 3.84 3.91 3.14 2.24 2.04 ...
La función summary() devuelve algunas de las medidas de dispersón de las variables numéricas de un data frame.
summary(df)
## x sin_of_x
## Min. : 1.00 Min. :2.041
## 1st Qu.: 3.25 1st Qu.:2.522
## Median : 5.50 Median :3.277
## Mean : 5.50 Mean :3.141
## 3rd Qu.: 7.75 3rd Qu.:3.795
## Max. :10.00 Max. :3.989
Recuerde cómo se veía nuestro data frame completo.
print(df)
## x sin_of_x
## 1 1 3.841471
## 2 2 3.909297
## 3 3 3.141120
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 7 7 3.656987
## 8 8 3.989358
## 9 9 3.412118
## 10 10 2.455979
Podemos extraer datos del data frame utilizando índices. En el siguiente caso, extraemos el dato de la variable #2 de la observación #1.
df[1, 2]
## [1] 3.841471
En el siguiente caso, extraemos el dato de la variable #2 de la observación #10.
df[10, 2]
## [1] 2.455979
Así mismo, podemos utilizar un vector de tamaño 1+n.
df[, 1:2]
## x sin_of_x
## 1 1 3.841471
## 2 2 3.909297
## 3 3 3.141120
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 7 7 3.656987
## 8 8 3.989358
## 9 9 3.412118
## 10 10 2.455979
df[c(3, 6), ]
## x sin_of_x
## 3 3 3.141120
## 6 6 2.720585
Podemos extraer observaciones completas.
df[10, ]
## x sin_of_x
## 10 10 2.455979
Podemos extraer el vector que compone una variable. En el siguiente caso, extraemos la variable #2.
df[, 2]
## [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
## [9] 3.412118 2.455979
También, podemos extraer el vector que compone una variable utilizando el nombre de la variable en lugar de su índice.
df[, "sin_of_x"]
## [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
## [9] 3.412118 2.455979
Finalmente, igual podemos extraer el vector que compone una variable utilizando $ + el nombre de la variable.
df$sin_of_x
## [1] 3.841471 3.909297 3.141120 2.243198 2.041076 2.720585 3.656987 3.989358
## [9] 3.412118 2.455979
💡 He aquí la importancia de que los nombres de una variable no tengan espacios y utilicen guiones bajos.
Podemos extraer una variable conservando el formato de un data frame utilizando únicamente el índice o el nombre de la variable dentro de los corchetes:
df[2]
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
df["sin_of_x"]
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
Observe cómo la estructura cambia.
str(df[, 2]) # Este es un vector
## num [1:10] 3.84 3.91 3.14 2.24 2.04 ...
str(df[2]) # Este es un data frame
## 'data.frame': 10 obs. of 1 variable:
## $ sin_of_x: num 3.84 3.91 3.14 2.24 2.04 ...
La forma en que extraigamos el contenido de una variable, dependerá del uso que querramos darle. No existe una forma “correcta” de hacerlo.
De igual forma, podemos extraer variabes de un data frame con la función subset().
subset(df, select=sin_of_x)
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
subset(df, select=2)
## sin_of_x
## 1 3.841471
## 2 3.909297
## 3 3.141120
## 4 2.243198
## 5 2.041076
## 6 2.720585
## 7 3.656987
## 8 3.989358
## 9 3.412118
## 10 2.455979
No siempre sabremos el índice de las observaciones que queremos extraer de un data frame. En la mayoría de los casos, queremos extraer observaciones con base en una o varias condiciones.
df[df[, 2] < 3, ]
## x sin_of_x
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 10 10 2.455979
df[df[, "sin_of_x"] < 3, ]
## x sin_of_x
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 10 10 2.455979
df[df$sin < 3, ]
## x sin_of_x
## 4 4 2.243198
## 5 5 2.041076
## 6 6 2.720585
## 10 10 2.455979
Para crear nuevas variables en un data frame, debemos asignar vectores nuevos vectores.
df$y <- 101:110 # Creamos una nueva variable asignándole la mu
print(df)
## x sin_of_x y
## 1 1 3.841471 101
## 2 2 3.909297 102
## 3 3 3.141120 103
## 4 4 2.243198 104
## 5 5 2.041076 105
## 6 6 2.720585 106
## 7 7 3.656987 107
## 8 8 3.989358 108
## 9 9 3.412118 109
## 10 10 2.455979 110
df$x_times_2 <- df$x * 2
print(df)
## x sin_of_x y x_times_2
## 1 1 3.841471 101 2
## 2 2 3.909297 102 4
## 3 3 3.141120 103 6
## 4 4 2.243198 104 8
## 5 5 2.041076 105 10
## 6 6 2.720585 106 12
## 7 7 3.656987 107 14
## 8 8 3.989358 108 16
## 9 9 3.412118 109 18
## 10 10 2.455979 110 20
df$x_times_2_flag <- df$x_times_2 > 10
print(df)
## x sin_of_x y x_times_2 x_times_2_flag
## 1 1 3.841471 101 2 FALSE
## 2 2 3.909297 102 4 FALSE
## 3 3 3.141120 103 6 FALSE
## 4 4 2.243198 104 8 FALSE
## 5 5 2.041076 105 10 FALSE
## 6 6 2.720585 106 12 TRUE
## 7 7 3.656987 107 14 TRUE
## 8 8 3.989358 108 16 TRUE
## 9 9 3.412118 109 18 TRUE
## 10 10 2.455979 110 20 TRUE
df$x_cat <- ifelse(df$x == 2, yes="x igual a 2", no="x no es igual a dos")
print(df)
## x sin_of_x y x_times_2 x_times_2_flag x_cat
## 1 1 3.841471 101 2 FALSE x no es igual a dos
## 2 2 3.909297 102 4 FALSE x igual a 2
## 3 3 3.141120 103 6 FALSE x no es igual a dos
## 4 4 2.243198 104 8 FALSE x no es igual a dos
## 5 5 2.041076 105 10 FALSE x no es igual a dos
## 6 6 2.720585 106 12 TRUE x no es igual a dos
## 7 7 3.656987 107 14 TRUE x no es igual a dos
## 8 8 3.989358 108 16 TRUE x no es igual a dos
## 9 9 3.412118 109 18 TRUE x no es igual a dos
## 10 10 2.455979 110 20 TRUE x no es igual a dos
Utilice el data frame construído en el ejercicio #2. 1. Instancie un nuevo objeto con un data frame que contenga únicamente la variable de nombre y de edad de aquellas personas con edad menor a la media de edad de todas las 10 personas. 2. En este segundo data frame, cree una nueva variable que indique la entidad federativa de cada uno de las personas. 3. Finalmente, en este segundo data frame, cree una nueva variable que indique si el nombre de la persona empieza con A, B o C de forma textual, es decir, con una cadena de caracteres.
df_txt <- read.table("./data/plain_txt.txt",
header = FALSE)
## Warning in read.table("./data/plain_txt.txt", header = FALSE): incomplete final
## line found by readTableHeader on './data/plain_txt.txt'
df_csv <- read.csv("./data/plain_csv.csv")
## Warning in read.table(file = file, header = header, sep = sep, quote = quote, :
## incomplete final line found by readTableHeader on './data/plain_csv.csv'
df_delim <- read.delim("./data/txt_with_delim.txt", sep="$")
## Warning in read.table(file = file, header = header, sep = sep, quote = quote, :
## incomplete final line found by readTableHeader on './data/txt_with_delim.txt'
library(readxl)
df_xlsx <- read_xlsx("./data/hoja_de_calculo.xlsx", sheet=1)
library(foreign)
# df_spss <- read.spss("example.sav",
# to.data.frame=TRUE,
# use.value.labels=FALSE) # SPSS data
# df_stata <- read.dta("example.dta") # Stata data
# file_url <- "https://data.cityofnewyork.us/api/views/kku6-nxdu/rows.csv?accessType=DOWNLOAD"
# download.file(file_url, destfile = "./data/demo_nyc.csv", method = "curl")
df_Demographic <- read.csv("./data/demo_nyc.csv")
Se recomienda ampliamente únicamente importar datos en formato csv.
# write.csv(df, file = ".data/cards.csv", row.names = FALSE)
print(df_delim)
## Col1 Col2 Col3
## 1 1 2 3
## 2 4 5 6
## 3 7 8 9
## 4 a b c
print(df_xlsx)
## # A tibble: 5 x 2
## x1 x2
## <dbl> <dbl>
## 1 1 2
## 2 2 4
## 3 3 6
## 4 4 8
## 5 5 10
merged_df <- merge(x = df_delim,
y = df_xlsx,
by.x = "Col1",
by.y = "x1",
all.x = T)
print(merged_df)
## Col1 Col2 Col3 x2
## 1 1 2 3 2
## 2 4 5 6 8
## 3 7 8 9 NA
## 4 a b c NA